home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / DJEMU106.ARJ / RMOV.CC < prev    next >
C/C++ Source or Header  |  1992-04-08  |  6KB  |  358 lines

  1. #include "emu.h"
  2. #include "const.h"
  3. #include "rmov.h"
  4.  
  5. extern "C" void djshld(void *v);
  6. extern "C" void djshrd(void *v);
  7.  
  8. void normalize(reg& r)
  9. {
  10.   if (!(r.sigl | r.sigh))
  11.   {
  12.     r.exp = 0;
  13.     r.tag = TW_Z;
  14.     return;
  15.   }
  16.   if (r.exp >= EXP_MAX)
  17.   {
  18.     r.tag = TW_S;
  19.     return;
  20.   }
  21.   while (!(r.sigh & 0x80000000))
  22.   {
  23.     if (r.exp == 0)
  24.       return;
  25.     djshld(&r.sigl);
  26.     r.exp--;
  27.   }
  28. }
  29.  
  30. void r_mov(long double *s, reg& d)
  31. {
  32.   unsigned long *sp = (unsigned long *)s;
  33.   if (sp[2] & 0x8000)
  34.     d.sign = SIGN_NEG;
  35.   else
  36.     d.sign = SIGN_POS;
  37.   d.exp = sp[2] & 0x7fff;
  38.   d.sigh = sp[1];
  39.   d.sigl = sp[0];
  40.   d.tag = TW_V;
  41.   normalize(d);
  42. }
  43.  
  44. void r_mov(double *s, reg& d)
  45. {
  46.   unsigned m64 = ((unsigned *)s)[1];
  47.   unsigned l64 = ((unsigned *)s)[0];
  48.   if (m64 & 0x80000000)
  49.     d.sign = SIGN_NEG;
  50.   else
  51.     d.sign = SIGN_POS;
  52.   if (!((m64 & 0x7fffffff) | (l64)))
  53.   {
  54.     int c = d.sign;
  55.     r_mov(CONST_Z, d);
  56.     d.sign = c;
  57.     return;
  58.   }
  59.   d.exp = (int)((m64>>20)&0x7ff) - 1023 + EXP_BIAS;
  60.   d.sigh = ((m64 & 0xfffff)<<11) | 0x80000000;
  61.   d.sigh |= l64 >> 21;
  62.   d.sigl = l64 << 11;
  63.   d.tag = TW_V;
  64.   if ((m64 & 0x7ff00000) == 0x7ff00000)
  65.     d.exp = EXP_MAX;
  66.   normalize(d);
  67. }
  68.  
  69. void r_mov(float *s, reg& d)
  70. {
  71.   unsigned m32 = *(unsigned *)s;
  72.   if (m32 & 0x80000000)
  73.     d.sign = SIGN_NEG;
  74.   else
  75.     d.sign = SIGN_POS;
  76.   if (!(m32 & 0x7fffffff))
  77.   {
  78.     int c = d.sign;
  79.     r_mov(CONST_Z, d);
  80.     d.sign = c;
  81.     return;
  82.   }
  83.   d.exp = (int)((m32>>23)&0xff) - 127 + EXP_BIAS;
  84.   d.sigh = ((m32 & 0x7fffff)<<8) | 0x80000000;
  85.   d.sigl = 0;
  86.   d.tag = TW_V;
  87.   if ((m32 & 0x7f800000) == 0x7f800000)
  88.     d.exp = EXP_MAX;
  89.   normalize(d);
  90. }
  91.  
  92. void r_mov(long long *_s, reg& d)
  93. {
  94.   long long s = *_s;
  95.   if (s == 0)
  96.     return r_mov(CONST_Z, d);
  97.  
  98.   if (s > 0)
  99.     d.sign = SIGN_POS;
  100.   else
  101.   {
  102.     s = -s;
  103.     d.sign = SIGN_NEG;
  104.   }
  105.  
  106.   int e = EXP_BIAS + 63;
  107.   while (s >= 0)
  108.   {
  109.     djshld(&s);
  110.     e -= 1;
  111.   }
  112.   d.sigh = s >> 32;
  113.   d.sigl = s;
  114.   d.exp = e;
  115.   d.tag = TW_V;
  116.   normalize(d);
  117. }
  118.  
  119. void r_mov(long *_s, reg& d)
  120. {
  121.   long s = *_s;
  122.   if (s == 0)
  123.     return r_mov(CONST_Z, d);
  124.  
  125.   if (s > 0)
  126.     d.sign = SIGN_POS;
  127.   else
  128.   {
  129.     s = -s;
  130.     d.sign = SIGN_NEG;
  131.   }
  132.  
  133.   int e = EXP_BIAS + 31;
  134.   while (!(s & 0x80000000))
  135.   {
  136.     s <<= 1;
  137.     e -= 1;
  138.   }
  139.   d.sigh = s;
  140.   d.sigl = 0;
  141.   d.exp = e;
  142.   d.tag = TW_V;
  143.   normalize(d);
  144. }
  145.  
  146. void r_mov(short *_s, reg& d)
  147. {
  148.   int s = *_s;
  149.   if (s == 0)
  150.     return r_mov(CONST_Z, d);
  151.  
  152.   if (s > 0)
  153.     d.sign = SIGN_POS;
  154.   else
  155.   {
  156.     s = -s;
  157.     d.sign = SIGN_NEG;
  158.   }
  159.  
  160.   int e = EXP_BIAS + 15;
  161.   while (!(s & 0x8000))
  162.   {
  163.     s <<= 1;
  164.     e -= 1;
  165.   }
  166.   d.sigh = s << 16;
  167.   d.sigl = 0;
  168.   d.exp = e;
  169.   d.tag = TW_V;
  170.   normalize(d);
  171. }
  172.  
  173. void r_mov(char *s, reg& d)
  174. {
  175.   int side=1, pos=8;
  176.   long long l;
  177.   l = 0;
  178.   for (int i=0; i<18; i++)
  179.   {
  180.     l *= 10;
  181.     switch (side)
  182.     {
  183.       case 0:
  184.         l += s[pos] & 0x0f;
  185.         side = 1;
  186.         pos--;
  187.         break;
  188.       case 1:
  189.         l += s[pos] >> 4;
  190.         side = 0;
  191.         break;
  192.     }
  193.   }
  194.   r_mov(&l, d);
  195.   if (s[9] & 0x80)
  196.     d.sign = SIGN_NEG;
  197. }
  198.  
  199. //=============================================================================
  200.  
  201. static void round_to_int(reg& r) // r gets mangled such that sig is int, sign
  202. {
  203.   reg t;
  204.   int more_than_half = 0;
  205.   int half_or_more = 0;
  206.   if (r.tag == TW_Z)
  207.   {
  208.     return;
  209.   }
  210.   while (r.exp < EXP_BIAS+62)
  211.   {
  212.     if (r.sigl & 1)
  213.       more_than_half = 1;
  214.     djshrd(&r.sigl);
  215.     r.exp++;
  216.   }
  217.   while (r.exp < EXP_BIAS+63)
  218.   {
  219.     if (r.sigl & 1)
  220.       half_or_more = 1;
  221.     djshrd(&r.sigl);
  222.     r.exp++;
  223.   }
  224.   if (r.exp > EXP_BIAS+63)
  225.   {
  226.     r.sigl = r.sigh = ~0;
  227.     return;
  228.   }
  229.   switch (control_word & CW_RC)
  230.   {
  231.     case RC_RND:
  232.       if (half_or_more)
  233.         if (more_than_half) // nearest
  234.           (*(long long *)(&r.sigl)) ++;
  235.         else
  236.           if (r.sigl & 1) // odd?
  237.             (*(long long *)(&r.sigl)) ++;
  238.       break;
  239.     case RC_DOWN:
  240.       if ((half_or_more||more_than_half) && r.sign)
  241.         (*(long long *)(&r.sigl)) ++;
  242.       break;
  243.     case RC_UP:
  244.       if ((half_or_more||more_than_half) && !r.sign)
  245.         (*(long long *)(&r.sigl)) ++;
  246.       break;
  247.     case RC_CHOP:
  248.       break;
  249.   }
  250. }
  251.  
  252. void r_mov(reg& s, long double *d)
  253. {
  254.   ((short *)d)[2] = s.exp + s.sign*0x8000;
  255.   ((long *)d)[0] = s.sigl;
  256.   ((long *)d)[1] = s.sigh;
  257. }
  258.  
  259. void r_mov(reg& s, double *d)
  260. {
  261.   unsigned long *l = (unsigned long *)d;
  262.   if (s.tag == TW_Z)
  263.   {
  264.     l[0] = 0;
  265.     l[1] = 0;
  266.   }
  267.   else
  268.   {
  269.     l[0] = (s.sigl >> 11) | (s.sigh << 21);
  270.     l[1] = ((s.sigh >> 11) & 0xfffff) | (((s.exp-EXP_BIAS+1023) & 0x7ff) << 20);
  271.   }
  272.   if (s.sign)
  273.     l[1] |= 0x80000000;
  274. }
  275.  
  276. void r_mov(reg& s, float *d)
  277. {
  278.   long f;
  279.   if (s.tag == TW_Z)
  280.   {
  281.     f = 0;
  282.   }
  283.   else
  284.   {
  285.     f = (s.sigh >> 8) & 0x007fffff;
  286.     f |= ((s.exp-EXP_BIAS+127) & 0xff) << 23;
  287.   }
  288.   if (s.sign)
  289.     f |= 0x80000000;
  290.   *(long *)d = f;
  291. }
  292.  
  293. void r_mov(reg& s, long long *d)
  294. {
  295.   reg t;
  296.   r_mov(s, t);
  297.   round_to_int(t);
  298.   ((long *)d)[0] = t.sigl;
  299.   ((long *)d)[1] = t.sigh;
  300.   if (t.sign)
  301.     *d = - *d;
  302. }
  303.  
  304. void r_mov(reg& s, long *d)
  305. {
  306.   reg t;
  307.   r_mov(s, t);
  308.   round_to_int(t);
  309.   if (t.sigh || (t.sigl & 0x80000000))
  310.     *d = -1;
  311.   else
  312.     *d = s.sign ? -t.sigl : t.sigl;
  313. }
  314.  
  315. void r_mov(reg& s, short *d)
  316. {
  317.   reg t;
  318.   r_mov(s, t);
  319.   round_to_int(t);
  320.   if (t.sigh || (t.sigl & 0xFFFF8000))
  321.     *d = -1;
  322.   else
  323.     *d = s.sign ? -t.sigl : t.sigl;
  324. }
  325.  
  326. void r_mov(reg& s, char *d)
  327. {
  328.   reg t;
  329.   r_mov(s, t);
  330.   round_to_int(t);
  331.   long long ll = *(long long *)(&t.sigl);
  332.   int side = 0;
  333.   int r, i;
  334.   for (i=0; i<10; i++)
  335.     d[i] = 0;
  336.   int pos=0;
  337.   for (i=0; i<18; i++)
  338.   {
  339.     r = ll % 10;
  340.     ll /= 10;
  341.     if (side)
  342.     {
  343.       d[pos] |= r << 4;
  344.       side = 0;
  345.       pos++;
  346.     }
  347.     else
  348.     {
  349.       d[pos] |= r;
  350.       side = 1;
  351.     }
  352.   }
  353.   if (s.sign == SIGN_NEG)
  354.     d[9] = 0x80;
  355. }
  356.  
  357.  
  358.